Release 10.1A: OpenEdge Development:
Progress 4GL Handbook


QUERY-PREPARE method

Once you’ve defined the buffers for a dynamic query, the next step is to provide it with a FOR EACH statement that it should use to retrieve and order data when you open the query. The QUERY-PREPARE method takes the FOR EACH statement as its argument. It returns true if the operation succeeded and false otherwise. You can use QUERY-PREPARE to define the record selection for a dynamic query or to change the selection for a static one. This sample code prepares the dynamic query for the Order, Customer, and SalesRep tables:

DEFINE VARIABLE hQuery    AS HANDLE     NO-UNDO. 
DEFINE VARIABLE iBufNum   AS INTEGER    NO-UNDO. 
DEFINE VARIABLE cBufNames AS CHARACTER  NO-UNDO. 
DEFINE VARIABLE lSuccess  AS LOGICAL    NO-UNDO. 
CREATE QUERY hQuery. 
hQuery:SET-BUFFERS(BUFFER Order:HANDLE, BUFFER Customer:HANDLE). 
hQuery:ADD-BUFFER(BUFFER SalesRep:HANDLE). 
lSuccess =  
    hQuery:QUERY-PREPARE("FOR EACH Order WHERE OrderStatus = 'Ordered', " 
                       + "FIRST Customer OF Order, "  
                       + "FIRST SalesRep OF Order " 
                       + "BY SalesRep"). 
IF NOT lSuccess OR ERROR-STATUS:NUM-MESSAGES NE 0 THEN 
DO: 
    /* Deal with possible errors in the Query Prepare. */ 
END. 

There are a few important comments to make about this example:

  1. Remember that when you use a one-to-one join in a FOR EACH statement for a query, you must include the FIRST or EACH keyword in each table phrase, as is shown in the following code example. Since there is just one Customer for each Order, and one SalesRep for each Order, there is no need to iterate through potentially multiple Customers or SalesReps for an Order, so the FIRST keyword suffices. In a FOR EACH statement in a block header, the FIRST keyword would be optional, as in this example:
  2. FOR EACH Order WHERE OrderStatus = "Ordered",  
        Customer OF Order, SalesRep OF Order: 
        DISPLAY OrderNum Order.CustNum Customer.NAME SalesRep.RepName. 
    END. 
    

  3. If you know exactly what the WHERE clause and BY clause are when you write the procedure, you might not need to use dynamic constructs at all. More realistically, you use the QUERY-PREPARE method when you don’t know the selection and sort criteria until run time. In the "Extending the sample window to filter dynamically" section, you’ll build an extension to the Customer and Orders window that shows this flexibility more realistically.
  4. Since you normally use the QUERY-PREPARE method in cases where the WHERE clause is truly variable, it is essential that you always assign the result of the method to a logical variable, and then check the value of that variable and the ERROR-STATUS:NUM-MESSAGES value to be sure that the prepare succeeded. If it doesn’t and you continue without intercepting the error, your procedure generates a whole series of error statements as you attempt to open and use the query.

Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095